use super::{configure_text_styles, dialog::*, setup_custom_fonts, widget::Dialog};

use eframe::egui;
use env_logger::Builder;
use std::io::Write;
use tokio::runtime::Runtime;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
enum Anchor {
    Delete,
    Copy,
    Move,
}

impl std::fmt::Display for Anchor {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{self:?}")
    }
}

impl Default for Anchor {
    fn default() -> Self {
        Self::Delete
    }
}

#[derive(Default)]
pub struct XFileApp {
    selected_anchor: Anchor,
    delete: DlgDelete,
}

//impl Default for XFileApp {
//    fn default() -> Self {
//        Self {
//            delete: DlgDelete::default(),
//            ..Default::default()
//        }
//    }
//}

impl eframe::App for XFileApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        self.update();
        egui::CentralPanel::default().show(ctx, |ui| self.ui(ui, ctx));
    }
}

impl XFileApp {
    pub fn run() -> Result<(), eframe::Error> {
        let mut builder = Builder::from_default_env();
        builder
            .format(|buf, record| writeln!(buf, "{} - {}", record.level(), record.args()))
            //.filter(None, LevelFilter::Info)
            .init();

        let rt = Runtime::new().expect("Unable to create Runtime");

        // Enter the runtime so that `tokio::spawn` is available immediately.
        let _enter = rt.enter();
        let options = eframe::NativeOptions {
            viewport: egui::ViewportBuilder::default()
                .with_inner_size([520.0, 356.0])
                .with_drag_and_drop(true),
            ..Default::default()
        };

        eframe::run_native(
            "X-File",
            options,
            Box::new(|cc| Box::new(XFileApp::new(cc))),
        )
    }

    pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
        // restore app state
        #[cfg(feature = "persistence")]
        if let Some(storage) = _cc.storage {
            if let Some(state) = eframe::get_value(storage, eframe::APP_KEY) {
                slf.state = state;
            }
        }

        setup_custom_fonts(&cc.egui_ctx);
        configure_text_styles(&cc.egui_ctx);

        let app = XFileApp::default();
        app
    }

    fn update(&mut self) {
        self.delete.update();
    }

    fn ui(&mut self, ui: &mut egui::Ui, ctx: &egui::Context) {
        self.ui_top_bar(ui, ctx);
        self.delete.ui(ui, ctx);
    }

    fn ui_top_bar(&mut self, _ui: &mut egui::Ui, ctx: &egui::Context) {
        egui::TopBottomPanel::top("x_file_top_bar").show(ctx, |ui| {
            ui.horizontal_wrapped(|ui| {
                //ui.visuals_mut().button_frame = false;
                egui::widgets::global_dark_light_mode_switch(ui);

                let mut selected_anchor = self.selected_anchor;
                for &(name, anchor) in self.menus_iter() {
                    ui.separator();
                    if ui
                        .selectable_label(selected_anchor == anchor, name)
                        .clicked()
                    {
                        selected_anchor = anchor.clone();
                    }
                }
                self.selected_anchor = selected_anchor;
            });
        });
    }

    fn menus_iter(&mut self) -> impl Iterator<Item = &(&str, Anchor)> {
        static MUTABLE_MENU: [(&str, Anchor); 3] = [
            ("删除", Anchor::Delete),
            ("复制", Anchor::Copy),
            ("移动", Anchor::Move),
        ];
        MUTABLE_MENU.iter()
    }
}
